/*
 * @Copyright: Copyright (c) 2019
 * @Author: 一枚小工
 * @Version: 1.0
 * @Date: 2019-10-28 17:28:38
 */
import { _decorator, Component, Node, systemEvent, RigidBodyComponent, UITransformComponent, Vec3, SpriteComponent, BoxColliderComponent, LabelComponent } from "cc";
const { ccclass, property } = _decorator;

enum State{
    Idle, // 空闲
    AddForce, // 加力
    ThrowOut, // 抛出
    Point, // 得分
}

@ccclass("BallCtrl")
export class BallCtrl extends Component {
    @property(UITransformComponent)
    private progress: UITransformComponent = null; // 力度显示

    @property(BoxColliderComponent)
    private colliderPoint: BoxColliderComponent = null; // 得分碰撞体

    @property(LabelComponent)
    private labelPoint: LabelComponent = null; // 得分显示

    private state: State = State.Idle; // 状态
    private body: RigidBodyComponent = null; // 刚体

    private static MIN_SPEED: number = 6; // 最小速度 (7.6,7.5,7.4)
    private static MAX_SPEED: number = 8; // 最大速度
    private static ADD_TIME:number = 3; // 加力最长时间

    private addDelta: number = 0; // 加力时间
    private growSpeed: number = (BallCtrl.MAX_SPEED - BallCtrl.MIN_SPEED) / BallCtrl.ADD_TIME; // 力变化速度
    private maxProgress: number = 0; // 最大进度长度值
    private point: number = 0; // 得分

    private startPos: Vec3 = null; // 开始位置

    private testSpeed:number = 7.4;

    onLoad(): void{
        this.startPos = cc.v3(this.node.position.x, this.node.position.y, this.node.position.z);
        this.maxProgress = this.progress.width;
        this.state = State.Idle;
        this.body = this.node.getComponent(RigidBodyComponent);
        this.body.useGravity = false;
        this.point = 0;

        this.setPercent(0);        

        systemEvent.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        systemEvent.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);

        this.colliderPoint.on('onTriggerEnter', this.onTriggerEnter, this);
        this.colliderPoint.on('onTriggerStay', this.onTriggerStay, this);
        this.colliderPoint.on('onTriggerExit', this.onTriggerExit, this);
    }    

    onTriggerEnter(): void{
        // cc.log('onTriggerEnter');
    }

    onTriggerStay(): void{
        // cc.log('onTriggerStay');
    }

    onTriggerExit():void {
        if(this.state != State.ThrowOut){
            return;
        }

        this.point++;
        this.labelPoint.string = `得分：${this.point}`;

        this.state = State.Point;
    }

    setPercent(percent: number): void{
        this.progress.width = percent * this.maxProgress;
    }

    onTouchStart(): void{
        if(this.state != State.Idle){
            return;
        }

        this.state = State.AddForce;
        this.addDelta = 0;    
    }

    onTouchEnd(): void{
        if(this.state != State.AddForce){
            return;
        }       

        this.state = State.ThrowOut;
        this.throwOutBall();
    }

    throwOutBall():void{
        // [7.4, 7.6]
        let speed: number = BallCtrl.MIN_SPEED + this.addDelta * this.growSpeed;
        // let speed:number = this.testSpeed;
        // this.testSpeed += 0.1;
        
        cc.log('speed', speed);

        let r:number = Math.PI / 3;

        let vy:number = speed * Math.sin(r);
        let vz:number = -speed * Math.cos(r);

        this.body.useGravity = true;
        this.body.setLinearVelocity(cc.v3(0, vy, vz));

        this.scheduleOnce(this.resetBall.bind(this), 3);
    }

    resetBall(): void{
        this.body.setLinearVelocity(Vec3.ZERO);
        this.body.setAngularVelocity(Vec3.ZERO);
        this.body.useGravity = false;
        this.node.setPosition(this.startPos);
        this.state = State.Idle;
        this.setPercent(0);
    }

    start (): void {
    }

    update (deltaTime: number): void {
        if(this.state != State.AddForce){
            return;
        }

        this.addDelta += deltaTime;

        if(this.addDelta > BallCtrl.ADD_TIME){
            this.addDelta = 0;
        }

        // this.addDelta = (this.addDelta > BallCtrl.ADD_TIME)? BallCtrl.ADD_TIME: this.addDelta;
        let percent: number = this.addDelta / BallCtrl.ADD_TIME;
        this.setPercent(percent);
    }
}
